<!DOCTYPE html>
<html>
    <head>
        <title>SPE: Dynamic properties</title>
        <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
        <style type="text/css">
            body {
                margin: 0;
                overflow: hidden;
            }

            #stats {
                position: absolute;
                top: 0;
                z-index: 2;
            }
        </style>
    </head>
    <body>
        <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.js"></script>
        <script type="text/javascript" src="./js/THREE-r84.js"></script>
        <script type="text/javascript" src="./js/Stats.min.js"></script>
        <script type="text/javascript" src="../build/SPE.min.js"></script>

        <script type="text/javascript">
            var scene = new THREE.Scene(),
                camera = new THREE.PerspectiveCamera( 64, window.innerWidth / window.innerHeight, 0.1, 10000 ),
                renderer = new THREE.WebGLRenderer( { antialias: true } ),
                stats = new Stats(),
                clock = new THREE.Clock(),

                group = new SPE.Group( {
                    // Possible API for animated textures...
                    texture: {
                        value: THREE.ImageUtils.loadTexture( './img/sprite-flame2.jpg' ),
                        frames: new THREE.Vector2( 8, 4 ),
                        // frameCount: 8,
                        loop: 2
                    },

                    depthTest: true,
                    scale: window.innerHeight / 2.0
                } ),

                emitter = new SPE.Emitter( {
                    particleCount: 200,
                    maxAge: {
                        value: 2,
                        spread: 0
                    },
                    position: {
                        value: new THREE.Vector3( 0, 0, 0 ),
                        spread: new THREE.Vector3( 10, 0, 0 ),
                        spreadClamp: new THREE.Vector3( 0, 0, 0 ),
                        distribution: SPE.distributions.BOX,
                        randomise: false
                    },
                    radius: {
                        value: 5,
                        spread: 0,
                        scale: new THREE.Vector3( 1, 1, 1 ),
                        spreadClamp: new THREE.Vector3( 2, 2, 2 ),
                    },
                    velocity: {
                        value: new THREE.Vector3( 0, 0, 0 ),
                        spread: new THREE.Vector3( 0, 0, 0 ),
                        // distribution: SPE.distributions.BOX,
                        randomise: false
                    },
                    acceleration: {
                        value: new THREE.Vector3( 0, 0, 0 ),
                        spread: new THREE.Vector3( 0, 0, 0 ),
                        // distribution: SPE.distributions.BOX,
                        randomise: false
                    },
                    drag: {
                        value: 0.5,
                        spread: 0
                    },
                    wiggle: {
                        value: 0,
                        spread: 0
                    },
                    rotation: {
                        axis: new THREE.Vector3( 0, 1, 0 ),
                        axisSpread: new THREE.Vector3( 0, 0, 0 ),
                        angle:  0, // radians
                        angleSpread: 0, // radians
                        static: false,
                        center: new THREE.Vector3( 0, 0, 0 )
                    },
                    size: {
                        value: 20,
                        spread: 0
                    },
                    opacity: {
                        value: 0.02
                    },
                    angle: {
                        value: 0,
                        spread: 0
                    }
                });

            group.addEmitter( emitter );
            scene.add( group.mesh );

            camera.position.z = 50;
            camera.position.y = 0;
            camera.lookAt( scene.position );


            // scene.fog = new THREE.Fog( 0x000000, 30, 50 );
            renderer.setClearColor( 0x222222, 0.1 );
            renderer.setSize( window.innerWidth, window.innerHeight );
            document.body.appendChild( renderer.domElement );
            document.body.appendChild( stats.domElement );

            window.addEventListener( 'resize', function() {
                var w = window.innerWidth,
                    h = window.innerHeight;

                renderer.setSize( w, h );
                camera.aspect = w / h;
                camera.updateProjectionMatrix();
                group.scale = group.uniforms.scale.value = h / 2.0;
            }, false );

            function initDAT() {
                var gui = new dat.GUI(),
                    keys = Object.keys( emitter ),
                    vec3Components = ['x', 'y', 'z'],
                    updateMaterial = function() {
                        group.material.needsUpdate = true;
                    },
                    i;

                var groupFolder = gui.addFolder( 'Group Settings' );

                groupFolder.add( group, 'textureLoop' ).min(1).max(10).step(1).onChange( function( value ) {
                    group.uniforms.textureAnimation.value.w = value;
                    updateMaterial();
                } );

                groupFolder.add( group, 'blending' ).min(0).max(5).step(1).onChange( function( value ) {
                    group.material.blending = value;
                    updateMaterial();
                } );
                groupFolder.add( group, 'colorize' ).onChange( function( value ) {
                    group.defines.COLORIZE = value;
                    updateMaterial();
                } );
                groupFolder.add( group, 'hasPerspective' ).onChange( function( value ) {
                    group.defines.HAS_PERSPECTIVE = value;
                    updateMaterial();
                } );
                groupFolder.add( group, 'transparent' ).onChange( function( value ) {
                    group.material.transparent = value;
                    updateMaterial();
                } );
                groupFolder.add( group, 'alphaTest' ).min(0).max(1).step(0.1).onChange( function( value ) {
                    group.material.alphaTest = value;
                    updateMaterial();
                }  );
                groupFolder.add( group, 'depthWrite' ).onChange( function( value ) {
                    group.material.depthWrite = value;
                    updateMaterial();
                }  );
                groupFolder.add( group, 'depthTest' ).onChange( function( value ) {
                    group.material.depthTest = value;
                    updateMaterial();
                }  );

                var positionFolder = gui.addFolder( 'Position' );
                var positionValue = positionFolder.addFolder( 'Value' );
                var positionSpread = positionFolder.addFolder( 'Spread' );
                var positionSpreadClamp = positionFolder.addFolder( 'Spread Clamp');

                for( i = 0; i < vec3Components.length; ++i ) {
                    positionValue.add( emitter.position.value, vec3Components[ i ], -100, 100 ).listen().onChange( function() {
                        emitter.position.value = emitter.position.value;
                    } );
                    positionSpread.add( emitter.position.spread, vec3Components[ i ], -100, 100 ).listen().onChange( function() {
                        emitter.position.spread = emitter.position.spread;
                    } );
                    positionSpreadClamp.add( emitter.position.spreadClamp, vec3Components[ i ], -50, 50 ).listen().onChange( function() {
                        emitter.position.spreadClamp = emitter.position.spreadClamp;
                    } );
                }

                positionFolder.add( emitter.position, 'radius', 0, 50 ).listen();
                positionFolder.add( emitter.position, 'randomise' ).listen();

                var velocityFolder = gui.addFolder( 'Velocity' );
                var velocityValue = velocityFolder.addFolder( 'Value' );
                var velocitySpread = velocityFolder.addFolder( 'Spread' );

                for( i = 0; i < vec3Components.length; ++i ) {
                    velocityValue.add( emitter.velocity.value, vec3Components[ i ], -50, 50 ).listen().onChange( function() {
                        emitter.velocity.value = emitter.velocity.value;
                    } );
                    velocitySpread.add( emitter.velocity.spread, vec3Components[ i ], -50, 50 ).listen().onChange( function() {
                        emitter.velocity.spread = emitter.velocity.spread;
                    } );
                }
                velocityFolder.add( emitter.velocity, 'randomise' ).listen();

                var accelerationFolder = gui.addFolder( 'Acceleration' );
                var accelerationValue = accelerationFolder.addFolder( 'Value' );
                var accelerationSpread = accelerationFolder.addFolder( 'Spread' );

                for( i = 0; i < vec3Components.length; ++i ) {
                    accelerationValue.add( emitter.acceleration.value, vec3Components[ i ], -50, 50 ).listen().onChange( function() {
                        emitter.acceleration.value = emitter.acceleration.value;
                    } );
                    accelerationSpread.add( emitter.acceleration.spread, vec3Components[ i ], -50, 50 ).listen().onChange( function() {
                        emitter.acceleration.spread = emitter.acceleration.spread;
                    } );
                }

                accelerationFolder.add( emitter.acceleration, 'randomise' ).listen();


                var colors = {
                    'Step 1': '#ffffff',
                    'Step 2': '#ffffff',
                    'Step 3': '#ffffff',
                    'Step 4': '#ffffff'
                };

                var colorFolder = gui.addFolder( 'Color steps' );
                colorFolder.addColor(colors, 'Step 1' ).onChange( function( value ) {
                    emitter.color.value[ 0 ].setStyle( value );
                    emitter.color.value = emitter.color.value;
                } );
                colorFolder.addColor(colors, 'Step 2' ).onChange( function( value ) {
                    emitter.color.value[ 1 ].setStyle( value );
                    emitter.color.value = emitter.color.value;
                } );
                colorFolder.addColor(colors, 'Step 3' ).onChange( function( value ) {
                    emitter.color.value[ 2 ].setStyle( value );
                    emitter.color.value = emitter.color.value;
                } );
                colorFolder.addColor(colors, 'Step 4' ).onChange( function( value ) {
                    emitter.color.value[ 3 ].setStyle( value );
                    emitter.color.value = emitter.color.value;
                } );

                var opacities = {
                    'Step 1': emitter.opacity.value[0],
                    'Step 2': emitter.opacity.value[1],
                    'Step 3': emitter.opacity.value[2],
                    'Step 4': emitter.opacity.value[3]
                };
                var opacityFolder = gui.addFolder( 'Opacity steps' );
                opacityFolder.add( opacities, 'Step 1' ).min(0).max(1).step(0.01).listen().onChange( function( value ) {
                    emitter.opacity.value[ 0 ] = value;
                    emitter.opacity.value = emitter.opacity.value;
                } );
                opacityFolder.add( opacities, 'Step 2' ).min(0).max(1).step(0.01).listen().onChange( function( value ) {
                    emitter.opacity.value[ 1 ] = value;
                    emitter.opacity.value = emitter.opacity.value;
                } );
                opacityFolder.add( opacities, 'Step 3' ).min(0).max(1).step(0.01).listen().onChange( function( value ) {
                    emitter.opacity.value[ 2 ] = value;
                    emitter.opacity.value = emitter.opacity.value;
                } );
                opacityFolder.add( opacities, 'Step 4' ).min(0).max(1).step(0.01).listen().onChange( function( value ) {
                    emitter.opacity.value[ 3 ] = value;
                    emitter.opacity.value = emitter.opacity.value;
                } );
            }

            function animate() {
                requestAnimationFrame( animate );
                stats.update();
                render();
            }

            function render() {
                var dt = clock.getDelta();
                group.tick( dt );
                renderer.render( scene, camera );
            }

            console.log( group );
            console.log( emitter );

            initDAT();
            animate();
        </script>
    </body>
</html>
